package com.jxt.mina.server;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.keepalive.KeepAliveFilter;
import org.apache.mina.filter.keepalive.KeepAliveMessageFactory;
import org.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

import com.jxt.mina.tools.CodecFactory;



/**
 * 启动mina服务
 * 
 * @author Scott.Wong
 * 
 */
public class Server extends Thread implements KeepAliveMessageFactory,
		KeepAliveRequestTimeoutHandler {

	private static Logger logger = Logger.getLogger(Server.class);
	private static final int PORT = 8082;
	/** 30秒后超时 */
	private static final int IDELTIMEOUT = 30;
	/** 15秒发送一次心跳包 */
	private static final int HEARTBEATRATE = 15;

	/** 心跳包内容 */
	private static final String HEARTBEATREQUEST = "HEARTBEATREQUEST";
	private static final String HEARTBEATRESPONSE = "HEARTBEATRESPONSE";

	public void run() {
		IoAcceptor acceptor = new NioSocketAcceptor();
		acceptor.addListener(new ServerListener());
		acceptor.getFilterChain().addLast("codec",
				new ProtocolCodecFilter(new CodecFactory()));
		// 设置读取数据的缓冲区大小
		acceptor.getSessionConfig().setReadBufferSize(2048);
		// 读写通道40秒内无操作进入空闲状态
		acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 120);
		
		
		/** 主角登场 */

		KeepAliveMessageFactory heartBeatFactory = new KeepAliveMessageFactoryImpl();
		KeepAliveRequestTimeoutHandler heartBeatHandler = new KeepAliveRequestTimeoutHandlerImpl();
		KeepAliveFilter heartBeat = new KeepAliveFilter(heartBeatFactory,
				IdleStatus.BOTH_IDLE, heartBeatHandler);
		/** 是否回发 */
		heartBeat.setForwardEvent(true);
		/** 发送频率 */
		heartBeat.setRequestInterval(HEARTBEATRATE);
		acceptor.getFilterChain().addLast("heartbeat", heartBeat);

		/** *********************** */
		
		
		// 绑定逻辑处理起器
		acceptor.setHandler(new ServerHandler());
		try {
			acceptor.bind(new InetSocketAddress(PORT));
			logger.info("服务器启动成功。。。。端口为：" + PORT);
		} catch (IOException e) {
			logger.error("服务器启动异常。。。。", e);
		}

	}
	
	
	/***
	 * @ClassName: KeepAliveMessageFactoryImpl
	 * @Description: 内部类，实现心跳工厂
	 * @author Minsc Wang ys2b7_hotmail_com
	 * @date 2011-3-7 下午04:09:02
	 * 
	 */
	private static class KeepAliveMessageFactoryImpl implements
			KeepAliveMessageFactory {

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.apache.mina.filter.keepalive.KeepAliveMessageFactory#getRequest
		 * (org.apache.mina.core.session.IoSession)
		 */
		@Override
		public Object getRequest(IoSession session) {
			return null;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.apache.mina.filter.keepalive.KeepAliveMessageFactory#getResponse
		 * (org.apache.mina.core.session.IoSession, java.lang.Object)
		 */
		@Override
		public Object getResponse(IoSession session, Object request) {
			//logger.info("返回预设语句" + HEARTBEATRESPONSE);
			/** 返回预设语句 */
			return HEARTBEATRESPONSE;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.apache.mina.filter.keepalive.KeepAliveMessageFactory#isRequest
		 * (org.apache.mina.core.session.IoSession, java.lang.Object)
		 */
		@Override
		public boolean isRequest(IoSession session, Object message) {
			//logger.info("是否是心跳包: " + message);
			if(message.equals(HEARTBEATREQUEST))
				return true;
			return false;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.apache.mina.filter.keepalive.KeepAliveMessageFactory#isResponse
		 * (org.apache.mina.core.session.IoSession, java.lang.Object)
		 */
		@Override
		public boolean isResponse(IoSession session, Object message) {
			//logger.info("是否是心跳包: " + message);
			if(message.equals(HEARTBEATRESPONSE))
				return true;
			return false;
		}

	}

	public Object getRequest(IoSession session) {
		return null;
	}

	public Object getResponse(IoSession session, Object request) {
		// logger.info("返回预设语句" + HEARTBEATRESPONSE);
		// /** 返回预设语句 */
		// return HEARTBEATRESPONSE;
		return null;
	}

	public boolean isRequest(IoSession session, Object message) {
		// logger.info("是否是心跳包: " + message);
		String string = message.toString();
		if (string.length() == 32) {
			//logger.info("是心跳包: " + message);
			return true;
		}
		//logger.info("不是心跳包");
		return false;
	}

	public boolean isResponse(IoSession session, Object message) {
		String string = message.toString();
		if (string.length() == 32) {
			//logger.info("是心跳包: " + message);
			return true;
		}
		//logger.info("不是心跳包");
		return false;
	}

	/***
	 * @ClassName: KeepAliveRequestTimeoutHandlerImpl
	 * @Description: 当心跳超时时的处理，也可以用默认处理 这里like
	 *               KeepAliveRequestTimeoutHandler.LOG的处理
	 * @author Minsc Wang ys2b7_hotmail_com
	 * @date 2011-3-7 下午04:15:39
	 * 
	 */
	public void keepAliveRequestTimedOut(KeepAliveFilter filter,
			IoSession session) throws Exception {
		String sessionid = (String) session.getAttribute("sessionId");
		//logger.info(sessionid);
		session.setAttribute("sessionId", null);
		//logger.info("心跳超时！");
	}
	
	
	/***
	 * @ClassName: KeepAliveRequestTimeoutHandlerImpl
	 * @Description: 当心跳超时时的处理，也可以用默认处理 这里like
	 *               KeepAliveRequestTimeoutHandler.LOG的处理
	 * @author Minsc Wang ys2b7_hotmail_com
	 * @date 2011-3-7 下午04:15:39
	 * 
	 */
	private static class KeepAliveRequestTimeoutHandlerImpl implements
			KeepAliveRequestTimeoutHandler {

		/*
		 * (non-Javadoc)
		 * 
		 * @seeorg.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler#
		 * keepAliveRequestTimedOut
		 * (org.apache.mina.filter.keepalive.KeepAliveFilter,
		 * org.apache.mina.core.session.IoSession)
		 */
		@Override
		public void keepAliveRequestTimedOut(KeepAliveFilter filter,
				IoSession session) throws Exception {
			((Logger) LOG).info("心跳超时！");
		}

	}

}
